


UNet = {
    Event : class {
        constructor(){
            this.events = []
        }
        on(eventName, fun, target) {
            this.events.push({ eventName: eventName, fun: fun, target: target });
        }
        off(eventName, fun, target) {
            if(typeof eventName == 'object' || typeof eventName == 'function'){
                return this.removeAllListeners(eventName);
            }
            this.events = this.events.filter(item => { return item.eventName != eventName || item.fun !== fun || item.target != target; });
        }
        emit(eventName, ...args) {
            let currentEvents = this.events.filter(item => { return item.eventName == eventName });
            currentEvents.map(item => {
                item.fun.apply(item.target, args);
            });
            this.events = this.events.filter(item => { return item.eventName != eventName || (item.eventName == eventName && !item.isOnce) });
        }
        removeAllListeners(eventName) {
            if(typeof(eventName) == 'object' || typeof eventName == 'function'){
                this.events = this.events.filter(item => { return item.target != eventName });
            } else {
                this.events = this.events.filter(item => { return item.eventName != eventName });
            }
        }
        once(eventName, fun, target) {
            this.events.push({ eventName: eventName, fun: fun, target: target, isOnce: true });
        }
        clean(){
            this.events = [];
        }
    },

    EventType : {
        OPEN : 'on_open',
        CLOSE : 'on_close',
        ERROR : 'on_error',
        
    },

    Socket : class {
        constructor(cfg){
            this.config = cfg;
            this.ws = null;
            this.host = cfg.host
            this.events = new UNet.Event()
            this.hTimeNum = 0;
            this.isActiveClose = false; //是否为主动断开连接
            this.hTimeInterval = -1
            this.reconnectCount = 0; //重连的次数
        }
        _initEvent(){
            this.ws.onmessage = (evt)=>{
                var data;
                try{
                    data = JSON.parse(evt.data);
                    if(data.e == 'p'){
                        this.hTimeNum = 0
                        return;
                    }
                }catch(e){
                    console.error('消息解析错误:',evt.data,e)
                }
                this.events.emit(data.e,data);
            }
            this.ws.onopen = () => {
                this._setOutH();
                console.log('socket onopen');
                this.reconnectCount = 5
                this.events.emit(UNet.EventType.OPEN)
            };
            this.ws.onclose = () => {
                console.log('websocket链接中断！', this.reconnectCount);
                if (!this.isActiveClose && this.reconnectCount && this.config.autoConnect) {
                    // console.log('2秒后自动重连！！');
                    setTimeout(() => {
                        this.ReConnect();
                    }, 2000);
                    this.reconnectCount--;
                    this.events.emit('reconnect',this.reconnectCount)
                } else {
                    this.events.emit('close')
                }
                this.events.emit(UNet.EventType.CLOSE)
            };
            this.ws.onerror = (e)=>{
                console.error('ws onerror:',e);
                this.events.emit(UNet.EventType.ERROR)
            }
        }

        Connect(){
            var url = this.config.isSSL ? 'wss://' : 'ws://'
            url += this.config.host +':'+this.config.port
            if (!!this.ws && this.ws.readyState == 1) { this.Close(); }
            this.ws = new WebSocket(url);
            this._initEvent();
            this.isActiveClose = false;
        }
        On() {
            this.events.on(...arguments);
        }
        Off() {
            this.events.removeAllListeners(...arguments);
        }
        Once() {
            this.events.once(...arguments);
        }
        RemoveListener() {
            this.events.removeListener(...arguments);
        }
        Close() {
            this.CalOutH();
            this.isActiveClose = true;
            try {
                console.log('close断开连接');
                this.ws.close();
            } catch (e) {
    
            }
        }
        ReConnect() {
            console.log('开始重连ws');
            this.Connect();
        }
        Send(k,v) {
            if(typeof(k) == 'object'){
                this.SendString(JSON.stringify(k));
            } else {
                this.SendString(JSON.stringify({e:k,v:v}));
            }
        }
        SendString(str) {
            if (!!this.ws && this.ws.readyState == 1) {
                this.ws.send(str);
            }
        }
        GetWsReadyState() {
            var status = false;
            if (this.ws && this.ws.readyState == 1) {
                status = true;
            }
            return status;
        }
        CalOutH() {
            // clearInterval(this.hTimeInterval);
            this.hTimeNum = 0;
        }
        _setOutH() {
            // this.hTimeInterval = setInterval(() => {
            //     this.hTimeNum++;
            //     if (this.hTimeNum > 4) {
            //         console.log('心跳超时');
            //         this.CalOutH();
            //         this.ws.close();
            //     }
            // }, 1000);
        }
    }
    
}